/*
 * SHOPTNT 版权所有。
 * 未经许可，您不得使用此文件。
 * 官方地址：www.shoptnt.cn
 */
package cn.shoptnt.service.pagedata.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.shoptnt.client.goods.GoodsClient;
import cn.shoptnt.framework.database.WebPage;
import cn.shoptnt.framework.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.shoptnt.framework.rabbitmq.MessageSender;
import cn.shoptnt.framework.rabbitmq.MqMessage;
import cn.shoptnt.framework.util.DateUtil;
import cn.shoptnt.framework.util.PageConvert;
import cn.shoptnt.framework.util.StringUtil;
import cn.shoptnt.mapper.system.PageDataGoodsMapper;
import cn.shoptnt.mapper.system.PageDataMapper;
import cn.shoptnt.model.base.message.CmsManageMsg;
import cn.shoptnt.model.base.rabbitmq.AmqpExchange;
import cn.shoptnt.model.errorcode.SystemErrorCode;
import cn.shoptnt.model.pagedata.PageData;
import cn.shoptnt.model.pagedata.PageDataGoods;
import cn.shoptnt.model.pagedata.PageQueryParam;
import cn.shoptnt.model.pagedata.enums.PageStatus;
import cn.shoptnt.model.payment.enums.ClientType;
import cn.shoptnt.service.pagedata.PageDataGoodsManager;
import cn.shoptnt.service.pagedata.PageDataManager;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 楼层业务类
 *
 * @author fk
 * @version v1.0
 * @since v7.0.0
 * 2018-05-21 16:39:22
 */
@Service
public class PageDataManagerImpl implements PageDataManager {

    @Autowired
    private PageDataMapper pageDataMapper;
    @Autowired
    private PageDataGoodsManager pageDataGoodsManager;
    @Autowired
    private PageDataGoodsMapper pageDataGoodsMapper;

    protected final Logger logger = LoggerFactory.getLogger(PageDataManagerImpl.class);


    @Override
    public WebPage getPageList(PageQueryParam param) {

        QueryWrapper<PageData> wrapper = new QueryWrapper<>();
        if (!StringUtil.isEmpty(param.getPublishStatus())) {
            wrapper.eq("publish_status", param.getPublishStatus());
        }
        wrapper.like(StringUtil.notEmpty(param.getKeyword()), "page_name", param.getKeyword());
        wrapper.eq("seller_id", param.getSellerId()).eq("client_type", param.getClientType());
        wrapper.orderByDesc("create_time");
        IPage<PageData> iPage = pageDataMapper.selectPage(new Page<>(param.getPageNo(), param.getPageSize()), wrapper);
        return PageConvert.convert(iPage);

    }

    @Override
    @Transactional(value = "systemTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public PageData add(PageData page) {
        page.setCreateTime(DateUtil.getDateline());
        page.setPublishStatus(PageStatus.NO.name());
        page.setIsIndex(PageStatus.NO.name());
        pageDataMapper.insert(page);
        //存储楼层关联的商品id
        this.getGoodsAndSave(page);
        return page;
    }

    @Override
    @Transactional(value = "systemTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public PageData edit(PageData page, Long id) {
        page.setId(id);
        pageDataMapper.updateById(page);
        //存储楼层关联的商品id
        this.getGoodsAndSave(page);
        return this.getModel(id);
    }

    @Override
    public PageData editIndex(Long sellerId, Long id) {
        PageData page = pageDataMapper.selectById(id);
        if (PageStatus.NO.name().equals(page.getPublishStatus())) {
            throw new ServiceException(SystemErrorCode.E806.code(), "页面未发布！不可设置为首页");
        }
        PageData pageData = this.getIndex(sellerId, page.getClientType());
        if (null != pageData) {
            pageData.setIsIndex(PageStatus.NO.name());
            pageDataMapper.updateById(pageData);
        }
        page.setId(id);
        page.setPublishStatus(PageStatus.YES.name());
        String status = page.getIsIndex().equals(PageStatus.NO.name()) ? PageStatus.YES.name() : PageStatus.NO.name();
        page.setIsIndex(status);

        pageDataMapper.updateById(page);
        //存储楼层关联的商品id
        this.getGoodsAndSave(page);
        return page;
    }

    @Override
    public PageData getIndex(Long sellerId, String clientType) {
        QueryWrapper<PageData> query = new QueryWrapper<>();
        query.eq("is_index", "YES").eq("client_type", clientType).eq("seller_id", sellerId);
        PageData pageData = pageDataMapper.selectOne(query);
        return pageData;
    }

    @Override
    @Transactional(value = "systemTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void delete(Long id) {
        PageData page = pageDataMapper.selectById(id);
        if (PageStatus.YES.name().equals(page.getIsIndex())) {
            throw new ServiceException(SystemErrorCode.E806.code(), "不能删除已发布的首页");
        }
        pageDataMapper.deleteById(id);
        //删除关联
        pageDataGoodsMapper.delete(new QueryWrapper<PageDataGoods>()
                .eq("page_id", id));
    }

    @Override
    public void delete(Long[] ids) {
        for (Long id : Arrays.asList(ids)) {
            delete(id);
        }
//        QueryWrapper<PageData> wrapper = new QueryWrapper<>();
//        wrapper.in("id", ids);
//        pageDataMapper.delete(wrapper);
    }

    @Override
    public PageData getModel(Long id) {
        PageData page = pageDataMapper.selectById(id);
        return page;
    }

    @Override
    public PageData updatePublish(Long id) {
        PageData page = getModel(id);
        if (null == page) {
            throw new ServiceException(SystemErrorCode.E806.code(), "页面不存在");
        }
        if (PageStatus.YES.name().equals(page.getIsIndex())) {
            throw new ServiceException(SystemErrorCode.E806.code(), "首页发布状态不能修改");
        }
        String status = page.getPublishStatus().equals(PageStatus.NO.name()) ? PageStatus.YES.name() : PageStatus.NO.name();
        page.setPublishStatus(status);
        pageDataMapper.updateById(page);
        return page;
    }


    /**
     * 楼层中找出商品数据并存储到对照表中
     *
     * @param pageData
     */
    private void getGoodsAndSave(PageData pageData) {

        //删除关联
        pageDataGoodsMapper.delete(new QueryWrapper<PageDataGoods>()
                .eq("page_id", pageData.getId()));

        //微页面json，找出goodslist，添加商品和楼层的对照关系，便于商品修改时，同时修改微页面
        String data = pageData.getPageData();
        JSONArray dataList = JSONArray.fromObject(data);
        List<Object> goodsIds = new ArrayList<>();

        dataList.forEach(json -> {
            JSONObject module = (JSONObject) json;
            JSONObject dataJson = module.getJSONObject("data");
            //模块名称
            String name = module.getString("name");
            if ("goods".equals(name) || "goods-slider".equals(name)) {
                //商品模块或者商品滑块
                //data.goodsList
                JSONArray goodsList = dataJson.getJSONArray("goodsList");
                goodsList.forEach(goods -> {
                    Object goodsId = ((JSONObject) goods).get("goods_id");
                    goodsIds.add(goodsId);
                });
            }
            //魔方,魔方中可能包含商品列表
            if ("magic-cube".equals(name)) {
                JSONArray blockList = dataJson.getJSONArray("blockList");
                blockList.forEach(block -> {
                    //商品data.blockList[].goodsList
                    JSONArray goodsList = (JSONArray) ((JSONObject) block).get("goodsList");
                    if (StringUtil.isNotEmpty(goodsList)) {
                        goodsList.forEach(goods -> {
                            Object goodsId = ((JSONObject) goods).get("goods_id");
                            goodsIds.add(goodsId);
                        });
                    }
                    //tab data.blockList[].tabList[].goodsList
                    JSONArray tabList = (JSONArray) ((JSONObject) block).get("tabList");
                    if (StringUtil.isNotEmpty(tabList)) {
                        tabList.forEach(tab -> {

                            JSONArray list = (JSONArray) ((JSONObject) tab).get("goodsList");
                            list.forEach(goods -> {
                                Object goodsId = ((JSONObject) goods).get("goods_id");
                                goodsIds.add(goodsId);
                            });
                        });
                    }
                });
            }
        });
        //将楼层中数据存储到楼层商品对照表中
        List<PageDataGoods> res = goodsIds.stream().map(goodsId -> {
            PageDataGoods pageDataGoods = new PageDataGoods();
            pageDataGoods.setGoodsId(Long.parseLong(goodsId.toString()));
            pageDataGoods.setPageId(pageData.getId());
            return pageDataGoods;
        }).collect(Collectors.toList());

        pageDataGoodsManager.saveBatch(res);
    }


}
